home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / HDX_BACK / HDX503 / DSMARK.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-09  |  13.1 KB  |  427 lines

  1. /*
  2.  *  Dsmark.c
  3.  *    Routines for performing a destructive markbad.
  4.  */
  5.  
  6. /* 23-Nov-87    ml.    just started.    
  7.  * 11-Nov-88    jye. change and add codes so that can be used for MS-DOS.
  8.  * 08-Aug-89    jye. change the max size of buffer for memory check.
  9.  */
  10.  
  11. #include "obdefs.h"
  12. #include "gemdefs.h"
  13. #include "osbind.h"
  14. #include "mydefs.h"
  15. #include "part.h"
  16. #include "bsl.h"
  17. #include "hdx.h"
  18. #include "addr.h"
  19.  
  20. extern SECTOR badbuf[];        /* bad sectors buffer */
  21.  
  22. extern int wdesk, hdesk;
  23. extern long nument();
  24. long sysize;                /* system memory size */
  25.  
  26. /*
  27.  *  Destructive Markbad for entire device.
  28.  *    Mechanism:
  29.  *        - write data to entire device, read it back, and compare
  30.  *          if there is any difference. (done in markdev())
  31.  *        - all new bad sectors are added to the bad sector list.
  32.  *          (done in markdev())
  33.  *        - repeat above for the number of passes passed in.
  34.  *    Input:
  35.  *        pdev - physical device number.
  36.  *        hdsiz - size of hard disk in sectors.
  37.  *        pass - number of passes to be performed.
  38.  *        pattern - data pattern to test the disk with.
  39.  *    Output:
  40.  *        bsl - bad sector list with added entries if any. (in bsl.h)
  41.  *    Return:
  42.  *        totbad - total number of bad sectors found.
  43.  *        ERROR - if any of the first 3 sectors is bad, or not enough
  44.  *            memory for buffer.
  45.  */
  46.  
  47. long
  48. dsmarkbad(pdev, hdsiz, pass, pattern)
  49. int pdev;    /* phys dev num */
  50. long hdsiz;    /* hard disk size */
  51. int pass;    /* num cycles */
  52. long pattern;    /* data pattern to test disk */
  53. {
  54.     char *inbuf;      /* buffer to hold data to be written to the disk */
  55.     char numbuf[10];
  56.     long totbad;      /* total num of bad sectors found */
  57.     long ret;          /* return code from markdev() */
  58.     long markdev();
  59.  
  60.     
  61.     /* Allocate memory for biggest data buffer necessary */
  62.     if ((sysize = Malloc(-1L)) <= 0)    {
  63.         return err(nomemory);
  64.     }
  65.     if ((sysize/512L) > MAXBUFSECT)     /*the max # of sector for hread() is 254*/ 
  66.         sysize = MAXBUFSECT * 512;     /*convert to bytes */
  67.  
  68.     if ((inbuf = (char *)Malloc(sysize)) <= 0)
  69.         return err(nomemory);
  70.  
  71.     /* Throw up message box to inform user about 
  72.        the processing of destructive markbad.  */
  73.     totbad = nument(VENDOR);  /* Number of existing VENDOR bad sectors */
  74.     ltoa(totbad, numbuf);
  75.     (dmrkmsg[OLDBAD].ob_spec)->te_ptext = numbuf;
  76.     strcpy((dmrkmsg[NEWBAD].ob_spec)->te_ptext, "0");  /* 0 new bad sector */
  77.     dmrkmsg[DMRKBAR].ob_width = 0;            /* haven't started yet */
  78.     dsplymsg(dmrkmsg);
  79.          
  80.     totbad = 0;    /* no NEW bad sectors yet */        
  81.     /* Loop for given number of passes */
  82.     while (pass) {
  83.         if ((ret = markdev(pdev, hdsiz, inbuf, pattern)) < 0) {
  84.             ret == ERROR;
  85.     } else {
  86.         totbad += ret;
  87.     }
  88.         pass--;
  89.     }
  90. wrapup:
  91.     erasemsg();
  92.     Mfree((long)inbuf);
  93.     if (ret < 0)
  94.         return (ret);
  95.     return(totbad);
  96. }
  97.  
  98.  
  99. /*
  100.  *  Fill up a character buffer with the given pattern.
  101.  *    Input:
  102.  *        buf - buffer to be filled.
  103.  *        size - size of buffer in bytes.
  104.  *        pattern - a 1-byte data to fill the buffer.
  105.  *    Output:
  106.  *        buf - buffer filled with the given pattern.
  107.  */
  108. fillbuf(buf, size, pattern)
  109. char *buf;
  110. long size;
  111. long pattern;
  112. {
  113.     long i;    /* index */
  114.     
  115.     for (i = 0; i < size; i += 4)
  116.     *(long *)&buf[i] = pattern;
  117. }
  118.  
  119. /*
  120.  * Fill the buffer with 0xffff start from giving pointer
  121.  * to the end of buffer.
  122.  */
  123.  
  124. fillfat(buf, start, size, pattern)
  125. char *buf;
  126. long start;
  127. long size;
  128. int pattern;
  129. {
  130.     long i;    /* index */
  131.     
  132.     for (i = start; i < size; i += 2)
  133.     *(int *)&buf[i] = pattern;
  134. }
  135.  
  136. /*
  137.  *  Markdev - Find bad sectors on a hard disk and record them in the Bad
  138.  *          Sector List.
  139.  *    Mechanism:
  140.  *        - write some given data to the entire device cylinder by
  141.  *          cylinder.
  142.  *        - read from the device cylinder by cylinder but in reverse
  143.  *          order.
  144.  *        - as data are read from the device, compare the written data
  145.  *          with the data read.  
  146.  *        - if there is any write, read or data error in a sector, that
  147.  *          sector will be considered bad.  (data error means data read
  148.  *          is different from data written.)
  149.  *        - add the bad sectors to the bad sector list.
  150.  *    Input:
  151.  *        pdev - physical device number.
  152.  *        hdsiz - size of hard disk in sectors.
  153.  *        databuf - buffer with the testing data.
  154.  *        pattern - data pattern to test with.
  155.  *    Output:
  156.  *        bsl - an updated bad sector list (ie. with newly found bad
  157.  *              sectors added to it).
  158.  *    Return:
  159.  *        totbad - total number of bad sectors found.
  160.  *        ERROR - Any of first 3 sectors on disk is bad.
  161.  */
  162. long
  163. markdev(pdev, hdsiz, databuf, pattern)
  164. int pdev;    /* phys dev number */
  165. long hdsiz;    /* size of hard disk in sectors */
  166. char *databuf;    /* testing data */ 
  167. long pattern;    /* data pattern */
  168. {
  169.     long sectcnt, cnt;        /* number of sectors to read */
  170.     long sect2mark;        /* number of sectors to mark */
  171.     SECTOR start, where;    /* where to start writing or reading */
  172.     long totbad;        /* total bad sectors found */
  173.     int nbad;            /* num bad sectors so far */
  174.     int ret=0;            /* return code from routines */
  175.     int clean;            /* indicate if chunk has any bad sector */
  176.     char numbuf[10];        /* buf to hold string converted from a number */
  177.  
  178.     
  179.     /*------------------------------------------------------------*/
  180.     /*  Write lots of sectors (MAXSECTS worth) at a time.      */
  181.     /*  If write error, loop through sectors within that cylinder */
  182.     /*  to find out exactly which sector(s) is bad, and add it to */
  183.     /*  the bad sector list if it's not already there.          */
  184.     /*------------------------------------------------------------*/
  185.  
  186.     sect2mark = hdsiz;        /* mark entire disk */
  187.     totbad = 0L;        /* no bad sectors yet */
  188.     nbad = 0;            /* no bad sectors found yet */
  189.     
  190.     start = 0L;
  191.     /* conver the bytes to the sectors */
  192.     sysize /= 512;
  193.     while (sect2mark != 0) {
  194.         /*
  195.         sbchk = 1;
  196.         */
  197.         if (sect2mark > sysize)
  198.             sectcnt = sysize;
  199.         else
  200.             sectcnt = sect2mark;
  201.             
  202.         /* fill buffer with given pattern */
  203.         fillbuf(databuf, (sectcnt << 9), pattern);
  204.             
  205. remwrs:
  206.         if ((ret = wrsects(pdev, (int)sectcnt, databuf, start)) != 0) {
  207.             /*
  208.             if ((ret == 0xffff)&&(sbchk))    {
  209.                 active(pdev);
  210.                 sbchk = 0;
  211.                 goto remwrs;
  212.             }
  213.             */
  214.             if (tsterr(ret) == OK) {
  215.                 ret = ERROR;
  216.                 goto badnews;
  217.             }
  218.             cnt = sectcnt;
  219.             where = start;
  220.             while (cnt) {
  221.                 if ((ret = wrsects(pdev, 1, databuf, where)) != 0) {
  222.             if (tsterr(ret) == OK) {
  223.             ret = ERROR;
  224.             goto badnews;
  225.             }
  226.                   if (where < 3) {
  227.                       ret = err(rsrvbad);
  228.                       goto badnews;
  229.                   }
  230.                     
  231.                      badbuf[nbad++] = where;    /* store bad sector num */
  232.                     
  233.                     /* buffer is filled up, have to add bad sectors
  234.                        found so far to the BSL before continuing.   */
  235.                     if (nbad == WARNBADSECTS) {
  236.                         if ((ret=addbsl(pdev, VENDOR, nbad)) < 0) {
  237.                             ret = ERROR;
  238.                             goto badnews;
  239.                         }
  240.                         totbad += ret;    /* increment num bad sectors existing */
  241.                         prnbad(totbad);
  242.                         nbad = 0;    /* start counting again */
  243.                     }
  244.                 }
  245.                 where++;
  246.                 cnt--;
  247.             }
  248.         }
  249.  
  250.     if (nbad) {    /* there are bad sectors found not added to BSL yet */
  251.         if ((ret = addbsl(pdev, VENDOR, nbad)) < 0) {
  252.         ret = ERROR;
  253.         goto badnews; 
  254.         }
  255.         totbad += ret;    /* increment num bad sectors existing */
  256.         prnbad(totbad);
  257.     }
  258.     
  259.         /*-----------------------------------------------------------*/
  260.         /* Read lots of sectors (one cylinder worth) at a time.      */
  261.         /* If read error, loop through sectors within that cylinder  */
  262.         /* to find out exactly which sector(s) is bad, and add it to */
  263.         /* the bad sector list if it's not already there.         */
  264.         /*                                 */
  265.         /* Data read is compared to data written.  If there is any   */
  266.         /* discrepancy within a sector, mark that sector as bad in   */
  267.         /* the bad sector list.                         */
  268.         /*-----------------------------------------------------------*/
  269.  
  270.         nbad = 0;    /* no bad sectors for this cylinder yet */
  271. remrds:
  272.         if ((ret = rdsects(pdev, (int)sectcnt, databuf, start)) != 0) {
  273.             /*
  274.             if ((ret == 0xffff)&&(sbchk))    {
  275.                 active(pdev);
  276.                 sbchk = 0;
  277.                 goto remrds;
  278.             }
  279.             */
  280.             if (tsterr(ret) == OK) {
  281.                 ret = ERROR;
  282.                 goto badnews;
  283.             }
  284.             cnt = sectcnt;
  285.             where = start;
  286.             while (cnt) {
  287.                 if ((ret = rdsects(pdev, 1, databuf, where)) != 0) {
  288.                     if (tsterr(ret) == OK) {
  289.                     ret = ERROR;
  290.                     goto badnews;
  291.                     }
  292.                     if (where < 3) {
  293.                       ret = err(rsrvbad);
  294.                       goto badnews;
  295.                   }
  296.                      badbuf[nbad++] = where;    /* store bad sector num */
  297.                 } else {
  298.                     if (!blktst(databuf, pattern, 512L)) {
  299.                         if (where < 3) {
  300.                           ret = err(rsrvbad);
  301.                           goto badnews;
  302.                       }
  303.                         badbuf[nbad++] = where;    /* store bad sector num */
  304.                     }
  305.                 }
  306.         /* buffer is filled up, have to add bad sectors
  307.                    found so far to the BSL before continuing.   */
  308.                 if (nbad == WARNBADSECTS) {
  309.                     if ((ret=addbsl(pdev, VENDOR, nbad)) < 0) {
  310.                         ret = ERROR;
  311.                         goto badnews;
  312.                     }
  313.                     totbad += ret;    /* incr num bad sectors existing */
  314.                     prnbad(totbad);
  315.                     nbad = 0;    /* start counting again */
  316.                 }
  317.                 where++;
  318.                 cnt--;
  319.             }
  320.             clean = 0;
  321.         } else {
  322.             clean = 1;
  323.         }
  324.         
  325.         if (nbad) { /* there are bad sectors found not added to BSL yet */
  326.             if ((ret = addbsl(pdev, VENDOR, nbad)) < 0) {
  327.                 ret = ERROR;
  328.                 goto badnews;
  329.             }
  330.             totbad += ret;    /* incr num bad sectors added to BSL */
  331.             prnbad(totbad);
  332.         } else if (clean) {
  333.         /* compare data read with data written, record bad sectors if any */
  334.             if ((ret = cmpdata(pdev, start, databuf, (int)sectcnt, pattern))
  335.                  < 0) {
  336.                 ret = ERROR;
  337.                 goto badnews;
  338.             } else {
  339.                 totbad += ret;    /* incr num bad sectors added to BSL */
  340.                 prnbad(totbad);
  341.             }
  342.         }
  343.         start += sectcnt;
  344.         sect2mark -= sectcnt;
  345.         
  346.         /* update bar on screen */
  347.         dmrkmsg[DMRKBAR].ob_width
  348.             = (dmrkmsg[DMRKBOX].ob_width * (hdsiz - sect2mark)) / hdsiz;
  349.     objc_draw(dmrkmsg, DMRKBAR, MAX_DEPTH, 0, 0, wdesk, hdesk);
  350.     }
  351. badnews:
  352.     if (ret < 0)        /* if an error occurs,            */
  353.         return(ret);        /*    return the error            */
  354.     else return(totbad);    /* else return number of bad sectors found. */
  355. }
  356.  
  357.  
  358. /*
  359.  *  Update number of bad sectors found during Destructive Markbad in
  360.  *  the dialogue box.
  361.  *    Input:
  362.  *        totbad - number of bad sectors found so far.
  363.  */
  364. prnbad(totbad)
  365. long totbad;
  366. {
  367.     char numbuf[10];
  368.     
  369.     ltoa(totbad, numbuf);
  370.     (dmrkmsg[NEWBAD].ob_spec)->te_ptext = numbuf;
  371.     objc_draw(dmrkmsg, NEWBAD, MAX_DEPTH, 0, 0, wdesk, hdesk);
  372. }
  373.  
  374. /*
  375.  *  Compare data read with data written of a cylinder, and mark sectors
  376.  *  with data error in the bad sector list.
  377.  *    Input:
  378.  *        pdev - physical unit BSL belongs to.
  379.  *        start - starting physical sector number of the cylinder.
  380.  *        databuf - data read from the cylinder.
  381.  *        numsect - number of sectors to be compared.
  382.  *        pattern - long pattern written on the cylinder.
  383.  *    Output:
  384.  *        bsl - an updated bad sector list with the newly found bad
  385.  *              sectors marked in it.
  386.  */
  387. cmpdata(pdev, start, readbuf, numsect, pattern)
  388. int pdev;    /* physical device number */
  389. SECTOR start;    /* phys sect num of where cylinder starts */
  390. BYTE *readbuf;    /* data read */
  391. int numsect;    /* num sectors to be compared */
  392. long pattern;    /* correct data pattern */
  393. {
  394.     int i, cnt;            /* indices into databuf, counter */
  395.     int nbad;            /* num bad sectors found so far */
  396.     int totbad;            /* total num bad sectors found in cylinder */
  397.     int ret;            /* return code from addbsl() */
  398.     
  399.     totbad = nbad = 0;    /* no bad sectors found yet */
  400.     
  401.     /* Test whole chunk first, if OK, ship it.  
  402.        Return 0 for no bad sectors found. */
  403.     if (blktst(readbuf, pattern, (long)numsect*512))
  404.         return 0;
  405.         
  406.     for (cnt = 0; cnt < numsect; cnt++) {
  407.         if (!blktst(readbuf, pattern, 512L)) {
  408.         badbuf[nbad++] = start + cnt;    /* store bad sector num */
  409.     }
  410.     readbuf += 512L;
  411.         if (nbad == WARNBADSECTS) {
  412.             if ((ret = addbsl(pdev, VENDOR, nbad)) < 0) {
  413.                 return ret;
  414.             }
  415.             totbad += ret;    /* incr num bad sectors added to BSL */
  416.             nbad = 0;        /* reinit counter for bad sectors to 0 */
  417.         }
  418.     }
  419.     if (nbad) {    /* bad sectors found but not added to BSL yet */
  420.         if ((ret = addbsl(pdev, VENDOR, nbad)) < 0) {
  421.             return ret;
  422.         }
  423.         totbad += ret;    /* incr num bad sectors added to BSL */
  424.     }
  425.     return(totbad);
  426. }
  427.